#!/usr/bin/env python
#-*- coding: utf-8 -*-

# Author: Edward Roualdes
#         University of Kentucky

from ConfigParser import SafeConfigParser
import multiprocessing
import os.path
import sys

# sanity checks are those helpful little comments that a program outputs
# to remind you of the options specified


def sane(CONFIGFILE):
    """perform sanity checks for NextAllele and output user specified options.
    """

    # parse CONFIGFILE
    parser = SafeConfigParser(dict_type = dict)
    parser.read(CONFIGFILE)

    # store [OPTIONS] in map
    ls = ['REFERENCEFILE', 'BARCODEFILE', 'INPUTFILE', \
          'OUTPUTDIRECTORY', 'BLASTREPORT']
    opts = {}                   # the map of options

    if 'OPTIONS' in parser.sections():
        for i in ls:
            val = parser.get('OPTIONS', i)
            if val:
                opts[i] = os.path.normpath(val)
            else:
                opts[i] = val
    else:
        print ("CONFIGFILE needs an [OPTIONS] section;"
               " see README file for an example.")
        sys.exit()

    # split ALIGNTOOL into list = [aligner, path]
    opts['ALIGNTOOL'] = parser.get('OPTIONS', 'ALIGNTOOL').split(', ')
    opts['ALIGNTOOL'][1] = os.path.normpath(opts['ALIGNTOOL'][1])

    # handle DO options
    opts['DO'] = parser.get('OPTIONS', 'DO').split(', ')
    opts['DO'] = [x.lower() for x in opts['DO']]

    # add [EXTRAS] to map if they exist
    # create sensible defaults defaults for extra options
    ls_extras = {'cpu': multiprocessing.cpu_count(),
                 'edit_pa': 'modified',
                 'cleansnp': True}
    int_extras = ['cpu']       # store [EXTRAS] that should be integer
    bool_extras = ['cleansnp'] # store [EXTRAS] that should be boolean

    # initialize [EXTRAS] to defaults
    for key, value in ls_extras.iteritems():
        opts[key] = value

    # allow users to change defaults
    if 'EXTRAS' in parser.sections() and parser.items('EXTRAS'):
        for name, value in parser.items('EXTRAS'):
            if value:                    # ie not ''
                if name in bool_extras: # booleans
                    opts[name] = parser.getboolean('EXTRAS', name)
                elif name in int_extras: # 
                    opts[name] = parser.getint('EXTRAS', name)
                else:
                    opts[name] = value

    # do appropriate files exist?
    for i in ls:
        if i not in ['OUTPUTDIRECTORY', 'BARCODEFILE']:
            if not os.path.exists(opts[i]):
                print i, 'does not exist.'
                sys.exit()
    if not os.path.exists(opts["ALIGNTOOL"][1]): 
        print "ALIGNTOOL path does not exist."
        sys.exit()



    # should sorting be performed
    opts['sort'] = True if 'sort' in opts['DO'] else False

    # should trimming be performed
    opts['trim'] = False if 'notrim' or not opts['sort'] else True

    # should aligning be performed
    opts['align'] = True if 'align' in opts['DO'] else False
        
    # should haplotype calling be performed
    opts['phase'] = True if 'phase' in opts['DO'] else False

    # should STRUCTURE file be created
    opts['structure'] = True if 'structure' in opts['DO'] else False

    # should PHASE program be run
    # otherwise phasetool can be left out of CONFIGFILE
    if 'runphase' in opts['DO']:

        # get path to PHASE
        opts['PHASETOOL'] = parser.get('OPTIONS', 'PHASETOOL')

        # does PHASE exist?
        if not os.path.exists(opts['PHASETOOL']):
            print "PHASE path does not exist."
            sys.exit()

        # tell NA to runphase
        opts['runphase'] = True
    else:
        opts['runphase'] = False

    # print options so that users are reminded of their input
    print "\nUser specified options:\n"
    for i in ls:
        print i, '=', opts[i]
    print 'ALIGNTOOL =', opts['ALIGNTOOL'][1]
    print 'sort =', opts['sort']
    print 'align =', opts['align']
    print 'phase =', opts['phase']
    print 'strucutre = ', opts['structure']
    print 'runPhase =', opts['runphase']
    print 'cpu =', opts['cpu']
    print "\n"

    return opts


if __name__ == '__main__':

    import sys
    import pprint

    pp = pprint.PrettyPrinter(indent=4)
    
    c = sys.argv[1]             # CONFIGILE
    pp.pprint(sane(c))
